package com.yubest.junit.encrypt.symmetric;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * 对称加密 aes
 *
 * @Author: hweiyu
 * @Date: 2022/11/11 15:44
 */
public class Aes {

    private static final String ALGORITHM = "AES";

    public static String encrypt(String data, String key) {
        byte[] res = exec(Cipher.ENCRYPT_MODE, data.getBytes(), key.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(res);
    }

    public static String decrypt(String data, String key) {
        byte[] bytes = Base64.getDecoder().decode(data);
        byte[] res = exec(Cipher.DECRYPT_MODE, bytes, key.getBytes());
        assert res != null;
        return new String(res, StandardCharsets.UTF_8);
    }

    private static byte[] exec(int mode, byte[] data, byte[] key) {
        try {
            //1.构造密钥生成器，指定为AES算法,不区分大小写
            KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
            //2.根据传入的字节数组，生成一个128位的随机源
            keyGenerator.init(128, new SecureRandom(key));
            //3.产生原始对称密钥
            SecretKey secretKey = keyGenerator.generateKey();
            //4.获得原始对称密钥的字节数组
            byte[] enCodeFormat = secretKey.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKeySpec keySpec = new SecretKeySpec(enCodeFormat, ALGORITHM);
            //6.根据指定算法AES自成密码器
            // 创建密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //7.初始化密码器，第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作，第二个参数为使用的KEY
            cipher.init(mode, keySpec);// 初始化
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
